{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#首先 import 必要的模块\n",
    "\n",
    "import numpy as np # linear algebra\n",
    "import pandas as pd # data processing, CSV file I/O\n",
    "\n",
    "import jieba\n",
    "\n",
    "import chardet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "UTF-8-SIG\n"
     ]
    }
   ],
   "source": [
    "#原始数据编码格式有误，更改后查询编码格式\n",
    "def get_encoding(file):\n",
    "    with open(file,'rb') as f:\n",
    "        return chardet.detect(f.read())['encoding']\n",
    "\n",
    "file_name=\"stopwords1.txt\"  #此处替换为你自己的文件路径\n",
    "encoding = get_encoding(file_name)\n",
    "print(encoding)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "14\n"
     ]
    }
   ],
   "source": [
    "#从文件导入停用词表\n",
    "def stop_words(path):\n",
    "    stpwrd_dic = open(path, 'r')\n",
    "    stpwrd_content = stpwrd_dic.read()\n",
    "    stpwrd_dic.close()\n",
    "    return stpwrd_content.splitlines()#将停用词表转换为list  \n",
    "\n",
    "stop_words=list(\"stopwords1.txt\")\n",
    "print(len(stop_words))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>target</th>\n",
       "      <th>content</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2</td>\n",
       "      <td>合晟资产是一家专注于股票、债券等二级市场投资，为合格投资者提供专业资产管理服务的企业。公司业...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>公司的主营业务为向中小微企业、个体工商户、农户等客户提供贷款服务，自设立以来主营业务未发生过变化。</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>公司立足于商业地产服务，致力于为商业地产开发、销售、运营全产业链提供一整套增值服务，业务覆盖...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2</td>\n",
       "      <td>公司经工商管理部门核准的经营范围为“投资咨询、经济信息咨询，企业管理咨询，品牌推广策划，公共...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2</td>\n",
       "      <td>该公司的主营业务为在中国境内(港、澳、台除外)开展保险代理销售，依托于自身的产品研究能力和专...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   target                                            content\n",
       "0       2  合晟资产是一家专注于股票、债券等二级市场投资，为合格投资者提供专业资产管理服务的企业。公司业...\n",
       "1       2  公司的主营业务为向中小微企业、个体工商户、农户等客户提供贷款服务，自设立以来主营业务未发生过变化。\n",
       "2       1  公司立足于商业地产服务，致力于为商业地产开发、销售、运营全产业链提供一整套增值服务，业务覆盖...\n",
       "3       2  公司经工商管理部门核准的经营范围为“投资咨询、经济信息咨询，企业管理咨询，品牌推广策划，公共...\n",
       "4       2  该公司的主营业务为在中国境内(港、澳、台除外)开展保险代理销售，依托于自身的产品研究能力和专..."
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "datapath = \"training.csv\"\n",
    "train = pd.read_csv(datapath,header=None, names=[\"target\", \"content\"])\n",
    "train.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building prefix dict from the default dictionary ...\n",
      "Loading model from cache /var/folders/_q/zfqvymyj2h529tdm7c3r80mw0000gn/T/jieba.cache\n",
      "Loading model cost 0.774 seconds.\n",
      "Prefix dict has been built succesfully.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0     合晟 资产 是 一家 专注 于 股票 、 债券 等 二级 市场 投资 ， 为 合格 投资者 ...\n",
       "1     公司 的 主营业务 为 向 中小 微 企业 、 个体 工商户 、 农户 等 客户 提供 贷款...\n",
       "2     公司 立足于 商业地产 服务 ， 致力于 为 商业地产 开发 、 销售 、 运营 全 产业链...\n",
       "3     公司 经 工商管理 部门 核准 的 经营范围 为 “ 投资 咨询 、 经济 信息 咨询 ， ...\n",
       "4     该 公司 的 主营业务 为 在 中国 境内 ( 港 、 澳 、 台 除外 ) 开展 保险代理...\n",
       "5     公司 主营业务 为 地铁 商业 物业 的 租赁 与 运营 管理 服务 。 公司 以 整体 租...\n",
       "6     作为 位于 南京市 江宁区 的 小额 信贷 融资 服务供应商 ， 公司 专注 于 满足 当地...\n",
       "7     公司 主要 为 商业 地产商 提供 服务 ， 主要 内容 为 项目前期 的 市场调研 ， 项...\n",
       "8     青岛 拥湾 资产 管理 集团股份 有限公司 ( 简称 “ 拥湾 资产 ” ， 股票代码 83...\n",
       "9     公司 的 主营业务 为 提供 物业管理 服务 ， 公司 自 成立 以来 主营业务 未 发生变...\n",
       "10    公司 提供 的 主要 服务 包括 ： 物业管理 ； 家政 服务 ； 洗染 服务 ； 建筑 清...\n",
       "11    根据 《 上市公司 行业 分类 指引 》 （ 2012 年 修订 ） ， 公司 所属 行业 ...\n",
       "12    公司 是 一家 从事 房地产 营销 的 顾问 代理 机构 ， 是 浙江 宁波 、 舟山 两地...\n",
       "13    公司 专业 从事 高档 写字楼 、 住宅 、 政府 机关 大楼 等 中高档 物业 项目 的 ...\n",
       "14    公司 主要 为 房地产 开发商 提供 传统 营销 代理服务 、 顾问 策划 服务 以及 基于...\n",
       "15    公司 以 平台 信息 服务 和 房屋交易 中介 服务 为 支点 ， 业务 覆盖 信息 咨询服...\n",
       "16    公司 系 一家 专注 于 供应链 体系 中 物流 与 生产 两大 产业 ， 以 保险 产品代...\n",
       "17    公司 主要 从事 私募 股权 投资 基金 管理 和 自有 资金 直接 股权 投资 ， 以及 ...\n",
       "18    公司 成立 于 2012 年 1 月 ， 注册资金 2.5 亿 ， 是 由 扬州 广电集团 ...\n",
       "19    公司 以 私募 股权 投资 基金 管理 为 主营业务 ， 系 国内 领先 的 专注 于 消费...\n",
       "Name: content, dtype: object"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X=train.iloc[:,1].apply(lambda sentence:' '.join(jieba.cut(sentence)))\n",
    "X.head(20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2 . 特征提取： 去掉停用词后（stop_words），采用TFIDF作为每个文本的特征描述。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<4774x30733 sparse matrix of type '<class 'numpy.float64'>'\n",
       "\twith 318818 stored elements in Compressed Sparse Row format>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "\n",
    "vector = TfidfVectorizer(stop_words=stop_words)\n",
    "tfidf = vector.fit_transform(X)\n",
    "tfidf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#原本类中的类别个数\n",
    "\n",
    "labels_true=train.iloc[:,0]\n",
    "cluster_num=len(set(labels_true))\n",
    "cluster_num"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3 . 采用KMeans聚类算法，选择合适的度量指标，选择最佳的K"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-means begin with clusters: 5\n",
      "K-means end with clusters: 5\n",
      "v_measure_score: 0.18312468868522835\n",
      "calinski_harabaz_score: 32.60569437773389\n",
      "silhouette_score: 0.008686150236964263\n",
      "K-means begin with clusters: 10\n",
      "K-means end with clusters: 10\n",
      "v_measure_score: 0.29712718477418926\n",
      "calinski_harabaz_score: 23.379713406885664\n",
      "silhouette_score: 0.011872691646597214\n",
      "K-means begin with clusters: 15\n",
      "K-means end with clusters: 15\n",
      "v_measure_score: 0.3138366752564478\n",
      "calinski_harabaz_score: 18.91278681563009\n",
      "silhouette_score: 0.013024384495436006\n",
      "K-means begin with clusters: 20\n",
      "K-means end with clusters: 20\n",
      "v_measure_score: 0.312337792811972\n",
      "calinski_harabaz_score: 15.977496094716109\n",
      "silhouette_score: 0.009639003187454764\n",
      "K-means begin with clusters: 25\n",
      "K-means end with clusters: 25\n",
      "v_measure_score: 0.35703972351811275\n",
      "calinski_harabaz_score: 13.97121435173462\n",
      "silhouette_score: 0.014990641323607763\n",
      "K-means begin with clusters: 30\n",
      "K-means end with clusters: 30\n",
      "v_measure_score: 0.3558234141463798\n",
      "calinski_harabaz_score: 12.616561933613706\n",
      "silhouette_score: 0.011678311445588752\n",
      "K-means begin with clusters: 35\n",
      "K-means end with clusters: 35\n",
      "v_measure_score: 0.3633726747182178\n",
      "calinski_harabaz_score: 11.787962723467704\n",
      "silhouette_score: 0.014531769806880954\n",
      "K-means begin with clusters: 40\n",
      "K-means end with clusters: 40\n",
      "v_measure_score: 0.3460202589460325\n",
      "calinski_harabaz_score: 10.805300486456218\n",
      "silhouette_score: 0.013042162139129593\n",
      "K-means begin with clusters: 45\n",
      "K-means end with clusters: 45\n",
      "v_measure_score: 0.3545476080392769\n",
      "calinski_harabaz_score: 10.164553456006098\n",
      "silhouette_score: 0.012659874411306369\n",
      "K-means begin with clusters: 50\n",
      "K-means end with clusters: 50\n",
      "v_measure_score: 0.3722033288649983\n",
      "calinski_harabaz_score: 9.482890718427623\n",
      "silhouette_score: 0.01453910449885702\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import normalize\n",
    "from sklearn import metrics\n",
    "from sklearn.cluster import KMeans\n",
    "\n",
    "def K_cluster_analysis(Ks, X):\n",
    "    SC_scores = []\n",
    "    CH_scores = []\n",
    "    VM_scores = []\n",
    "    for K in Ks:\n",
    "        print(\"K-means begin with clusters: {}\".format(K))\n",
    "        y_pred = KMeans(n_clusters=K, n_jobs=-1).fit_predict(X)\n",
    "        print(\"K-means end with clusters: {}\".format(K))\n",
    "        \n",
    "        vm = metrics.v_measure_score(labels_true, y_pred) #本案例中训练数据有标签，可采用有参考模型的评价指标\n",
    "        print(\"v_measure_score: {}\".format(vm))\n",
    "        \n",
    "        ch = metrics.calinski_harabaz_score(X, y_pred) #这两个分数值越大则聚类效果越好\n",
    "        print(\"calinski_harabaz_score: {}\".format(ch))\n",
    "        \n",
    "        sh = metrics.silhouette_score(X, y_pred) #轮廓系数Silhouette Coefficient在大样本时计算太慢\n",
    "        print(\"silhouette_score: {}\".format(sh))\n",
    "        \n",
    "        CH_scores.append(ch)\n",
    "        SC_scores.append(sh)\n",
    "        VM_scores.append(vm)\n",
    "    return CH_scores,SC_scores,VM_scores\n",
    "\n",
    "Ks = [5,10,15,20,25,30,35,40,45,50]\n",
    "CH_scores,SC_scores,VM_scores=K_cluster_analysis(Ks,tfidf.toarray())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#去量纲\n",
    "\n",
    "ch = [float(x - np.min(CH_scores))/(np.max(CH_scores)- np.min(CH_scores)) for x in CH_scores]\n",
    "sc = [float(x - np.min(SC_scores))/(np.max(SC_scores)- np.min(SC_scores)) for x in SC_scores]\n",
    "vm = [float(x - np.min(VM_scores))/(np.max(VM_scores)- np.min(VM_scores)) for x in VM_scores]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CH_Best_K: 5\n",
      "SC_Best_K: 25\n",
      "VM_Best_K: 50\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制不同K对应的聚类的性能，找到最佳模型／参数（分数最高）\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "%matplotlib inline\n",
    "\n",
    "plt.plot(Ks, np.array(ch), 'r-', label = 'CH_scores')\n",
    "plt.plot(Ks, np.array(sc), 'g-', label = 'SC_scores')\n",
    "plt.plot(Ks, np.array(vm), 'b-', label = 'VM_scores')\n",
    "plt.legend(loc='best')\n",
    "plt.xlabel( 'Calinski-Harabasz Index & Silhouette Coefficient & V Measure' )                                                                                    \n",
    "plt.ylabel( 'score' )\n",
    "\n",
    "### 最佳超参数\n",
    "index = np.unravel_index(np.argmax(CH_scores, axis=None), len(CH_scores))\n",
    "Best_K = Ks[index[0]]\n",
    "print('CH_Best_K:',Best_K)\n",
    "\n",
    "index = np.unravel_index(np.argmax(SC_scores, axis=None), len(SC_scores))\n",
    "Best_K = Ks[index[0]]\n",
    "print('SC_Best_K:',Best_K)\n",
    "\n",
    "index = np.unravel_index(np.argmax(VM_scores, axis=None), len(VM_scores))\n",
    "Best_K = Ks[index[0]]\n",
    "print('VM_Best_K:',Best_K)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "       \n",
    "      calinski_harabaz_score随着K的增加而递减，最佳k值是5； silhouette_score随着K的增加而抖动增减，最佳k值是25； v_measure_score随着K的增加而抖动增加，最佳k值是5\n",
    "      我认为原数据只有11类，我们也应该聚成11类，而上图可知，K=11时，几个指标均较稳定在较高处，所以确定K=11\n",
    "      K-means不保证达到全局最优（收敛，但没有达到全局最优），如上测试结果可见，调参过程存在很大的评分抖动，很难找出让所有指标都最优的参数，所以训练时要明确任务需要关注的指标，以此指标为目标调优即可。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
